package it.ilgrv.demiurgo.persistence;


import java.util.Stack;

import javax.persistence.EntityManager;
import javax.persistence.RollbackException;

import org.apache.log4j.Logger;

public class HandleTable {

	private static final Logger log = Logger.getLogger(HandleTable.class);

	protected EntityManager em;
	private Stack<Boolean> activeTransactionStack;

	public HandleTable(EntityManager em) {
		activeTransactionStack =new Stack<Boolean>();
		this.em = em;
	}

	/**
	 * inizia una nuova transazione solo se non c' una transazione attiva. da
	 * terminare con una chiamata endTransaction
	 */
	public void beginTransaction() {
		Boolean b = em.getTransaction().isActive();

		activeTransactionStack.push(b);

		if (!b) {
			em.getTransaction().begin();
			log.trace("transazione attivata");
		}
	}

	/**
	 * completa una chiamata beginTransaction: se la transazione era attiva la
	 * termina gestisce errori nel commit, eseguendo una rollback
	 * 
	 * @return true se  stato eseguito un commit, false se  stato eseguito un
	 *         rollback
	 */
	public boolean endTransaction() {

		Boolean b = activeTransactionStack.pop();
		try {
			if (!b) {
				if (em.getTransaction().getRollbackOnly()) {
					rollback();
					return false;
				} else {
					log.trace("Commit");
					em.getTransaction().commit();
					return true;
				}

			}
		} catch (RollbackException e) {
			log.warn("Rollback", e);
			rollback();
			return false;
		}

		return false;
	}

	public void rollback() {
		if (em.getTransaction().isActive()) {
			log.trace("Rollback");
			em.getTransaction().rollback();

		}
	}

	public boolean isInTransaction() {
		return em.getTransaction().isActive();
	}

	public EntityManager getEm() {
		return em;
	}

	/**
	 * ends the operation of the HandleTable, it must be called to avoid wrong
	 * resource utilization with DB
	 */
	public void close() {
		em.close();
	}


}
